<?php
/**
 * Subclass of DateTime, adding functionality to DateTime.
 *
 * @package be.appcraft.util
 * @version $Revision: 1.2 $
 *
 * @author Stijn Van Bael
 * @since 1.0
 */
class Pageley_Util_Timestamp implements Pageley_Util_Comparable {

	const MILLISECONDS = 1;
	const SECONDS = 1000;
	const MINUTES = 60000;
	const HOURS = 3600000;
	const DAYS = 86400000;
	const WEEKS = 604800000;

	private $time;
	private $date;

	/**
	 * Creates a new Timestamp
	 *
	 * @param string $time: Unix timestamp in seconds.
	 */
	public function __construct($time = null) {
		if($time === null) {
			$time = round(microtime(true) * 1000);
		}
		$this->time = $time;
		$this->date = new DateTime(date("Y-m-d H:i:s", $time / 1000));
	}

	/**
	 * Formats this Timestamp with the specified pattern. See {@link
	 * http://www.php.net/date} for more on date patterns.
	 *
	 * @param string $format: the pattern to format this Timestamp with.
	 * @return this Timestamp, formatted with the specified pattern
	 */
	public function format($pattern = "Y-m-d H:i:s") {
		return $this->date->format($pattern);
	}

	public function getTime() {
		return $this->time;
	}

	public static function parse($expression, $format = "Y-m-d H:i:s") {
	    $result = null;
        if($expression !== null && $expression != "") {
            $format = Pageley_Util_String::replace($format, "/", "\/");
            $regex = "/^" . preg_replace(array("/d/", "/Y/", "/m/", "/H/", "/i/", "/s/"),
                array("(?<day>\d{2})", "(?<year>\d{4})", "(?<month>\d{2})", "(?<hour>\d{2})",
                "(?<minute>\d{2})", "(?<second>\d{2})"), $format) . "$/";
            $matches = array();
            if(!preg_match_all($regex, $expression, $matches)) {
                throw new Pageley_Util_ParseException("Could not parse '" . $expression . "' as timestamp. Expected format: " . $format . "");
            }
            $hour = key_exists("hour", $matches) ? $matches["hour"][0] : 0;
            $minute = key_exists("minute", $matches) ? $matches["minute"][0] : 0;
            $second = key_exists("second", $matches) ? $matches["second"][0] : 0;
            $month = $matches["month"][0];
            $day = $matches["day"][0];
            $year = $matches["year"][0];
            $result = new Pageley_Util_Timestamp(mktime($hour, $minute, $second, $month, $day, $year) * 1000);
        }
        return $result;
	}

	public function __toString() {
		return $this->format();
	}

	public function equals($timestamp) {
		if($timestamp instanceof Pageley_Util_Timestamp) {
			return $this->getTime() == $timestamp->getTime();
		}
		return null;
	}

	public function compareTo($timestamp, $unit = 1) {
		return round(($this->time - $timestamp->getTime()) / $unit);
	}
}